package com.yht.weblog.web.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yht.weblog.common.domain.dos.ArticleCategoryRelDO;
import com.yht.weblog.common.domain.dos.ArticleDO;
import com.yht.weblog.common.domain.dos.CategoryDO;
import com.yht.weblog.common.domain.mapper.ArticleCategoryRelMapper;
import com.yht.weblog.common.domain.mapper.ArticleMapper;
import com.yht.weblog.common.domain.mapper.CategoryMapper;
import com.yht.weblog.common.enums.ResponseCodeEnum;
import com.yht.weblog.common.exception.BizException;
import com.yht.weblog.common.utils.PageResponse;
import com.yht.weblog.common.utils.Response;
import com.yht.weblog.web.convert.ArticleConvert;
import com.yht.weblog.web.model.vo.category.FindCategoryArticlePageListReqVO;
import com.yht.weblog.web.model.vo.category.FindCategoryArticlePageListRspVO;
import com.yht.weblog.web.model.vo.category.FindCategoryListRspVO;
import com.yht.weblog.web.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author: yht
 * @date: 2024/1/12 22:00
 * @description:
 **/
@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private ArticleCategoryRelMapper articleCategoryRelMapper;

    /**
     * 获取分类列表
     *
     * @return
     */
    @Override
    public Response findCategoryList() {
        // 查询所有分类
        List<CategoryDO> categoryDOS = categoryMapper.selectList(Wrappers.emptyWrapper());

        List<FindCategoryListRspVO> vos = null;

        // DO 转 VO
        if (!CollectionUtils.isEmpty(categoryDOS)) {
            vos = categoryDOS.stream().map(categoryDO -> FindCategoryListRspVO.builder()
                            .id(categoryDO.getId())
                            .name(categoryDO.getName())
                            .build())
                    .collect(Collectors.toList());
        }
        return Response.success(vos);
    }

    /**
     * 分类文章分页列表
     *
     * @param findCategoryArticlePageListReqVO 分类文章分页列表请求对象
     * @return 分类文章分页列表响应对象
     */
    @Override
    public Response findCategoryArticlePageList(FindCategoryArticlePageListReqVO findCategoryArticlePageListReqVO) {

        Long categoryId = findCategoryArticlePageListReqVO.getId();  // 获取分类ID
        Long current = findCategoryArticlePageListReqVO.getCurrent();  // 获取当前页码
        Long size = findCategoryArticlePageListReqVO.getSize();  // 获取每页显示数量

        CategoryDO categoryDO = categoryMapper.selectById(categoryId);  // 通过分类ID查询分类信息

        if (Objects.isNull(categoryDO)) {  // 如果分类信息为空
            log.warn("==> 分类不存在，categoryId:{}", categoryId);  // 打印日志，提示分类不存在
            throw new BizException(ResponseCodeEnum.CATEGORY_NOT_EXISTED);  // 抛出业务异常，表示分类不存在
        }

        // 查询分类下所有关联的文章 ID
        List<ArticleCategoryRelDO> articleCategoryRelDOS = articleCategoryRelMapper.selectListByCategoryId(categoryId);

        if (CollectionUtils.isEmpty(articleCategoryRelDOS)) {  // 如果文章列表为空
            log.warn("==> 分类下没有文章，categoryId:{}", categoryId);  // 打印日志，提示分类下没有文章
            return PageResponse.success(null, null);  // 返回空的分页响应
        }

        List<Long> articleIds = articleCategoryRelDOS.stream().map(ArticleCategoryRelDO::getArticleId).collect(Collectors.toList());  // 获取文章ID列表

        Page<ArticleDO> articleDOPage = articleMapper.selectPageListByArticleIds(current, size, articleIds);  // 通过文章ID列表查询文章分页信息
        List<ArticleDO> articleDOS = articleDOPage.getRecords();  // 获取文章分页信息中的文章列表

        List<FindCategoryArticlePageListRspVO> vos = null;  // 初始化空的分类文章列表

        if (!CollectionUtils.isEmpty(articleDOS)) {  // 如果文章列表不为空
            vos = articleDOS.stream()  // 转换文章DO列表为分类文章VO列表
                    .map(articleDO -> ArticleConvert.INSTANCE.convertDO2CategoryArticleVO(articleDO))  // 使用ArticleConvert工具类将文章DO转换为分类文章VO
                    .collect(Collectors.toList());  // 聚合分类文章VO列表

        }
        return PageResponse.success(articleDOPage, vos);  // 返回分类文章分页列表响应对象
    }

}
